home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / macros / inrstex / texgraph / texgraph.tex < prev    next >
Text File  |  1991-09-16  |  33KB  |  860 lines

  1. % DVIPS version 
  2.  
  3. % included are the changes required to make it work with DVIPS 
  4. % It should be modifiable to any other decent driver too
  5.  
  6. % This is the complete texgraph macros ... for use with the INRS/Beebe 
  7. % Postscript driver
  8.  
  9. % This is the INRSTEX version 
  10.  
  11. % Graphics macros for TeX using POSTCRIPT
  12.  
  13. % ----- Needs mod to count characters in special ... some drivers have an
  14. %   input limit of 500 characters in a \special 
  15.  
  16.  
  17. % ===============================================================
  18. % THIS VERSION IS FOR USE with a PostScript Driver with
  19. %          \p@sfile     to signal a file name 
  20. %          \p@sinline    to signal inline PostScript 
  21. %    processes \specials and dvi commands in order. 
  22. %    does not place a (save restore) pair about a \special. 
  23. %
  24. %   \printhv defines scale/directions for inline Postscript
  25. %   \filehv  defines scale/directions for file Postscript
  26. %  
  27. %  Both INRS's modification of Beebe's DVIALW and ArborText's PostScript 
  28. %    drivers satisfy these minimal requirements. 
  29.  
  30. % It assumes that the underlying units are 300 pix/in
  31. % Standard PostScript Conventions 
  32. % This is easily changed by changing the \hpix or \vpix
  33. % It assumes that x,y are in the "normal" up/left direction.
  34.  
  35. % File inclusions require the existence of a bounding box for the correct
  36. % spacing to be left. 
  37.  
  38. % ===============================
  39. % Most arguments, excepting file names, are delimited by spaces. Thus 
  40. % braces { .... } will usually only occur around inserted text ... which
  41. % still must be followed by a space or end of line. 
  42.  
  43.  
  44. % ======================
  45.  
  46. \catcode`\@=11
  47.  
  48. % =============== Driver Signal Forms =======================
  49.  
  50. %\xdef\p@sfile{ps: } % file signal INRS DVIALW
  51.  \xdef\p@sfile{ps: plotfile } % file signal DVIPS
  52. \xdef\p@sinline{ps:: }     % inline signal DVIPS ... INRS DVIALW
  53.  
  54. % This translates the direction of the page if the printer assumptions
  55. %  are different than TeX. The values should be +-1. 
  56. \gdef\printhv #1 #2 {\gdef\p@hv{ #1 #2 scale }}
  57. \gdef\filehv #1 #2 {\gdef\f@schv{ #1 #2 scale }} 
  58. \gdef\rtdir #1 {\gdef\r@tdir{ #1 }} % neg or  nothing PS has no pos 
  59.  
  60.  
  61.  
  62.  
  63.  
  64. % ============== LateX support =================
  65.  
  66. %\newenvironment{TeXgraph}{\btg}{\etg}
  67.  
  68. % This is the only change between the LateX and INRSTeX versions 
  69.  
  70. % ======= Simple Plotfile support ===========
  71.  
  72. %  These are vanilla  forms for inserting an encapsulated PostScript file
  73. %  or creating a centered graphics environment. 
  74.  
  75. % \centergraph needs to be very \long 
  76.  
  77. \long\gdef\centergraph#1{\hbox to 
  78.                 \hsize{\hss\vbox{#1\vgraphskip}\hgraphskip\hss}}
  79. \gdef\centerplotfile#1{\centergraph{\btg\includefile {#1} \etg}}
  80.  
  81.  
  82. % if you use the Latex command to create the new texgraph environment, 
  83. % then you will automatically be "inside" Texgraph. This
  84. % means that you should use such commands as 
  85. %  \includefile  \incscmvfile \incscfile 
  86.  
  87.  
  88.  
  89.  
  90. % ========= error messages =========
  91. % \language=0 -- English, 1 - French
  92. \ifnum \language=0 \message{<< WARNING -- TeXGraph needs DVIPS >>}
  93.                    \xdef\bbmess{Searching for BoundingBox }
  94.                    \xdef\incfile{Graphics file}
  95.                    \xdef\badincfile{Size/Format Error in Graphics File}
  96.                    \xdef\noincfile{Missing Graphics File}
  97.              \else
  98.                    \message{<< AVERTISSMENT -- TeXGraph a besoin du DVIPS >>}
  99.                    \xdef\bbmess{Searching for BoundingBox }
  100.                    \xdef\incfile{Graphics file}
  101.                    \xdef\badincfile{Size/Format Error in Graphics File}
  102.                    \xdef\noincfile{Missing Graphics File}
  103.              \fi
  104.  
  105. % ===== debugging code ===== 
  106. % will send out specials as messages 
  107. \gdef\dmess #1{}
  108. \gdef\bmess #1{}
  109.  
  110. % ======== \global\newif =======
  111. % Plain defines the \newif as a local variable. We need a global
  112. % version if TeXgraph is to be brought in while inside a group.
  113. % This is a simpler, but less elegant version of \newif
  114.  
  115. %#1 is \if<..> #2 -...true #3 ...false
  116. \gdef\gnewif#1#2#3{\global\let#1=\iffalse \gdef#2{\let#1=\iftrue}\relax
  117.                           \gdef#3{\let#1=\iffalse}}
  118.  
  119. % ======== TeXGraph Macros ==========
  120.  
  121. % Postcript allows for arbitrary translation, scaling, rotation and clipping.
  122. % This version saves the current segment scale(s), unit scale(s), rotation 
  123. % and translation and painfully computes and retores the correct form after 
  124. % a segment exit. The reason for this is that Postcript can stack only one 
  125. % CTM, text needs to have correct rotation and translation but default
  126. % scaling ...
  127.  
  128. % It would be preferable not to convert any of the units. However, it is 
  129. % necessary to know the maximum excursions. Since the PS currentpoint is 
  130. % not accessible to TeX, we must keep it ourselves. 
  131. % Since negative numbers can be used both maximum and minimum excursions 
  132. % are required. 
  133.  
  134.  
  135. % ====== begin -- end graphics =======
  136.  
  137. % The maximum and minimum extent in the h and v direction is recorded 
  138. % and is accessible
  139. % at the end of a \btg \etg pair (in points). The same value, in pixels is accessible at
  140. % all times 
  141. \newcount\maxhpospix
  142. \newcount\maxvpospix
  143. \newcount\minhpospix
  144. \newcount\minvpospix
  145. \newdimen\hgraphsize
  146. \newdimen\vgraphsize
  147.  
  148. \gdef\vgraphskip{\vskip\vgraphsize}
  149. \gdef\hgraphskip{\hskip\hgraphsize}
  150.  
  151.  
  152. \gdef\beginTeXGraphics{\t@exgraphdef \i@ncgdepth  
  153.                     \vbox\bgroup\offinterlineskip
  154.                      \h@pos=0 
  155.                      \global\maxhpospix=\h@pos 
  156.                      \global\minhpospix=\h@pos 
  157.                      \v@pos=0
  158.                    \global\maxvpospix=\v@pos 
  159.                    \global\minvpospix=\v@pos 
  160.                      \h@segoff=\h@pos \v@segoff=\v@pos
  161.                      \edef\o@form{}\ifnum\g@depth=1  
  162.                      \p@sinit  \fi \p@sset % PS initialization 
  163.                       \s@save}
  164. % \s@save saves the initialization for the special output.
  165. % \g@save saves some local condition 
  166.  
  167. \gdef\endTeXGraphics{\g@raphout\egroup\maxhvpos\p@srestore \d@ecgdepth }
  168. \global\let\btg=\beginTeXGraphics
  169. \global\let\etg=\endTeXGraphics
  170. \global\let\btg=\beginTeXGraphics
  171. \global\let\etg=\endTeXGraphics
  172.  
  173. % ========== TeXGraph Nesting Depth ==========
  174. \newcount\g@depth \global\g@depth=0 % initializes at zero
  175. \gdef\i@ncgdepth{\global\advance\g@depth by 1 }
  176. \gdef\d@ecgdepth{\global\advance\g@depth by -1 }
  177.  
  178.  
  179.  
  180. % =========== Complete Graph Scaling ===============
  181. % There is a separate scaling for the horizontal, vertical, and text
  182.  
  183.  
  184. \gdef\grscale h:#1 v:#2 {\gdef\h@grsc{#1}\gdef\v@grsc{#1}\e@xtend 
  185.                            {\o@form}{#1 #2 scale }}
  186.                            
  187. \gdef\tgrscale #1 {\e@xtend{\o@form}{#1 #1 scale }}
  188.               % text scale h and v the same
  189.  
  190.  
  191.  
  192.  
  193. % ======== PostScript initialization =========
  194.  
  195. \gdef\t@exgrdictdef{/td 50 dict def }
  196.  
  197.  
  198.  
  199. \gdef\t@exgrdictinit{ td begin  /mv {moveto} def
  200.                                  /lv {lineto} def
  201.                                  /st {stroke} def
  202.                                  /np {newpath} def
  203.                                  /sl {setlinewidth} def
  204.                                  /sd {setdash} def
  205.                                  /rt {rotate} def
  206.                                  /gs {gsave} def
  207.                                  /gr {grestore} def
  208.                                  /tr {translate} def
  209.                                  /cp {closepath} def
  210.                                  /sg {setgray} def
  211.                                  /chv {currentpoint} def
  212.                                  /cv {curveto} def
  213.                                  /slc {setlinecap} def
  214.                                  /slj {setlinejoin} def
  215.                                  /sc {scale} def
  216.                                  /at {neg atan rt} def
  217.                                  /mx {mv gs chv tr} def  
  218. %                                 \h@vinit
  219.                                 end }        
  220. % ----- initial point move ... driver dependent -----
  221. \gdef\Xpos{Xp\the\g@depth\b@}
  222. \gdef\Ypos{Yp\the\g@depth\b@}
  223.  
  224. \gdef\h@vinit{ chv /\Ypos   exch 
  225.                def /\Xpos  exch def }
  226. \gdef\h@vset{\t@rhv  \p@hv }
  227. \gdef\m@vhv{ \Xpos   \Ypos   mv } % INRS
  228. \gdef\t@rhv{ \Xpos  \Ypos  tr } % INRS
  229. \gdef\t@rneghv{ \Xpos neg \Ypos neg tr } % INRS
  230.                      
  231. \gdef\p@sinit{\edef\e@form{\special{\p@sinline   
  232.                                \t@exgrdictdef 
  233.                                \t@exgrdictinit}}
  234. \gdef\p@sset{\special{\p@sinline  td begin \h@vinit gs \t@rhv 
  235.                                    \p@hv end }}\e@form\dmess{\e@form}} 
  236.  
  237. % ======== PostScript termination =========
  238. \gdef\p@srestore{\edef\e@form{\special{\p@sinline  grestore }}\e@form
  239.                             \dmess{\e@form}}
  240.                % resets to entry into TeXgraph and recovers memory 
  241.  
  242. %========= macros for converting dimensions/units =========
  243. % --------- \box0 must not be void ----------
  244. \global\setbox0=\hbox{}
  245.  
  246. %default values
  247. \gdef\graphdim#1 {\gdef\g@dim{#1\relax}}
  248.  
  249. %pixels /dim unit
  250. \newcount\h@pix  % sp/pixel 
  251. \gdef\hpix#1/#2 {\wd0=1true#2\relax
  252.          \h@pix=\wd0 \divide\h@pix by #1 \relax}
  253. \newcount\v@pix  % sp/pixel 
  254. \gdef\vpix#1/#2 {\wd0=1true#2\relax
  255.          \v@pix=\wd0 \divide\v@pix by #1 \relax}
  256.  
  257. % Assumes #1 is dimension #2 is count in pixels, #3 sp/pix, #4 scalefactor (real)
  258. % #2 is returned
  259. \gdef\gendimtopix#1#2#3#4{\wd0=#1\dimen0=#4\wd0\relax
  260.                   \wd0=\dimen0 #2=\wd0 \divide #2 by #3\relax}
  261. % #1 is returned, #5 -\global or {}
  262. \gdef\genpixtopt#1#2#3#4#5{\multiply #2 by #3\relax\wd0=#2sp
  263.                       #5#1=#4\wd0\relax}
  264.  
  265. % ---------- Converts maxpix to maxdim removes offset -----
  266. \gdef\maxhvpos{\global\advance\maxhpospix by -\minhpospix\relax
  267.            \genpixtopt{\hgraphsize}{\maxhpospix}{\h@pix}{\h@grsc}{\global}\relax
  268.               \global\advance\maxvpospix by -\minvpospix\relax
  269.                    \genpixtopt{\vgraphsize}{\maxvpospix}{\v@pix}{\v@grsc}{\global}}
  270.  
  271.  
  272.  
  273. % ======== The vector offsets my be relative or absolute =====
  274.  
  275. \gnewif{\ifr@elpos}{\r@elpostrue}{\r@elposfalse} %default is absolute 
  276. \gdef\absoluteposition{\r@elposfalse}
  277. \gdef\relativeposition{\r@elpostrue}
  278. \global\let\abspos=\absoluteposition 
  279. \global\let\relpos=\relativeposition 
  280. \global\let\absolute=\absoluteposition % historical
  281. \global\let\relative=\relativeposition % historical
  282.  
  283. % ====== update #1 by #2 r@elpos to #3, #4 is max #5 is min=======
  284. \gdef\u@pdate#1#2#3#4#5{\ifr@elpos \advance #1 by #2\else
  285.                         \advance #2 by #3\relax
  286.                            #1=#2\fi
  287.                     \ifnum #1>#4\global #4=#1\fi
  288.                     \ifnum #1<#5\global #5=#1\fi
  289.                     }
  290. \gdef\h@update #1{\u@pdate{\h@pos}{#1}{\h@segoff}{\maxhpospix}{\minhpospix}}
  291. \gdef\v@update #1{\u@pdate{\v@pos}{#1}{\v@segoff}{\maxvpospix}{\minvpospix}}
  292.  
  293. % === pixel position r@elpos to initial offset starting position
  294. \newcount\h@pos \h@pos=0
  295. \newcount\v@pos \v@pos=0
  296. \newcount\r@ang \r@ang=0 % 1000 times degrees ?
  297.  
  298.  
  299. % ===== Check for pen up moves only =====
  300. % penup/down are used to determine whether a line needs to be stroked 
  301. % when a line pattern or penwidth is changed. 
  302.  \gnewif{\ifp@down}{\p@downtrue}{\p@downfalse} 
  303.  
  304.  
  305. % ===== present segment origin and rotation ==========
  306.  
  307. \newcount\h@segoff
  308. \newcount\v@segoff 
  309. \newcount\r@segoff % 1000 times degrees 
  310.  
  311.  
  312. \gdef\beginsegment{\g@raphout\begingroup\s@eginit}
  313.  
  314. % segment initialization is a trifle messy 
  315. \gdef\s@eginit{\h@segoff =\h@pos \v@segoff=\v@pos}
  316.  
  317.  
  318. % PS has the concept of a path  that is either 
  319. % completed with a "stroke" or "fill" ... stroking 
  320. % at the end or beginning of a segment, the special is written out. This is 
  321. % to ensure that the input order of the graphics reflects what entities are
  322. % on top of what others. Further it is assumed that the origin does not
  323. % change during an entire \btg ...\etg section. This means that every special
  324. % must first move to the point where the previous one left off. \s@save
  325. % defines \s@restore that restores, in case they had been modified, the line 
  326. % width, pattern, hpos, vpos, ... and any future things that need restoration.
  327. % all graphic specials are ended with a stroke (st), whether it needs it not. 
  328.  
  329. % we need a special form to force a space after a \the\nnn form or \p@w 
  330.  
  331. \gdef\b@{ }
  332.  
  333. \gdef\endsegment{\g@raphout\endgroup
  334.        \edef\o@form{}\s@save}
  335. \gdef\s@pout #1#2{\edef\e@form{\special{#1\s@restore\o@form#2}}\dmess{\e@form}\e@form
  336.                   \edef\o@form{}\s@save}
  337. %\h@vset if there is  a move before each special 
  338. \gdef\g@raphout{\ifx\empty\o@form \else \ifp@down 
  339.                  \s@pout{\p@sinline  td begin }{ st end }\fi\fi\p@downfalse}
  340. \global\let\graphout=\g@raphout
  341.  
  342. % ====== Segment and units scaling ========
  343. % The units in any segment may be scaled arbitrarily. A unit scale is local
  344. % to a segment but affects enclosed segments unless specifically overidden 
  345. % in that segment. In addition there is a graph or segment scale. This
  346. % scaling factor is accumulative and is applied on top of the unit scale.
  347. % These two scaling factors allow for a segment to be designed in nominal
  348. % units, scaled to a nominal size and then be affected by relative scaling
  349. % of an entire graph or segment. In addition there is a relative/absolute
  350. % scale switch that allows for any segment to be unaffected by a graphscale.
  351.  
  352. % \u@nitsc -- present unit scale, \s@egsc -- present segment scale
  353. % \g@rsc -- present graphscale ... changes when ever either of the former do.
  354.  
  355. % present implementation does not allow separate v h scaling
  356.  
  357. % ------ Relative/Absolute Scale ------
  358. \gnewif{\ifr@elscale}{\r@elscaletrue}{\r@elscalefalse}
  359. \gdef\absolutescale{\r@elscalefalse}
  360. \gdef\relativescale{\r@elscaletrue}
  361. \global\let\abssc=\absolutescale
  362. \global\let\relsc=\relativescale
  363.  
  364. % ----- unit scale -----
  365. \gdef\unitscale#1 {\edef\u@nitsc{#1}\newgraphscale}
  366.  
  367. \global\let\graphscale=\unitscale % Historical 
  368.  
  369. % ----- Segment Scale -----
  370.  
  371. \gdef\segmentscale#1 {\ifr@elscale \realmult{#1}{\s@egsc}{\s@egsc}\else
  372.                           \edef\s@egsc{#1}\fi
  373.                        \newgraphscale}
  374.  
  375. % ---- Graph Scale --------
  376. % This changes whenever either of the above change
  377. \gdef\newgraphscale{\realmult{\u@nitsc}{\s@egsc}{\g@rsc}}
  378.  
  379.  
  380. % ------ "Real" Multiplication --------
  381. % These functions use the fact that a box dimension may be scaled by
  382. % a real. The final step is to "clean" off the pt on the resulting dim
  383.  
  384. % Cleans off the pt in a dimension ... pt has catcode 12
  385. {\catcode`\p=12 \catcode`\t=12
  386. \gdef\c@lean#1pt{\edef\cx{#1}}}
  387. % #1 and #2 are multiplicands #3 is a command to capture result
  388. \gdef\realmult#1#2#3{\wd0=1pt\dimen0=#1\wd0\wd0=\dimen0\dimen0=#2\wd0
  389.                    \edef\R@M{\the\dimen0}\expandafter\c@lean\R@M\edef#3{\cx}}
  390. \gdef\realadd#1#2#3{\dimen0=#1pt\dimen2=#2pt\advance\dimen0by\dimen2
  391.                    \edef\R@M{\the\dimen0}\expandafter\c@lean\R@M\edef#3{\cx}}
  392.  
  393.  
  394. % -------- Command to convert nominal values to pixels ------
  395. % #1 is a decimal number, #2 must be a count, #3 is sp/pix
  396. % This includes all scalings
  397. \gdef\grdimtopix#1#2#3{\gendimtopix{#1\g@dim}{#2}{#3}{\g@rsc}}
  398.  
  399.                 
  400. % ------- special forms to update positions ------
  401.  
  402. \gdef\i@h#1{\grdimtopix{#1}{\d@umc}{\h@pix}\h@update{\d@umc}}
  403. \gdef\i@v#1{\grdimtopix{#1}{\d@umc}{\v@pix}\v@update{\d@umc}}
  404. \gdef\h@num#1#2{\grdimtopix{#1}{#2}{\h@pix}}
  405. \gdef\v@num#1#2{\grdimtopix{#1}{#2}{\v@pix}}
  406.  
  407.  
  408. %dummy variables
  409. \newcount\d@uma
  410. \newcount\d@umb
  411. \newcount\d@umc
  412. \newcount\d@umd
  413. \newcount\d@ume
  414.  
  415. % ====== end macros for converting dimensions
  416.  
  417. % ======== Some more Utility Macros ========
  418. % ======== recursive macros ========
  419. \gdef\e@xtend #1#2{\let\d@x=#1\edef #1{\d@x #2}}
  420. \xdef\s@pex{}
  421. \xdef\s@pin{ }
  422. \gdef\s@pexpand #1 #2!{\e@xtend{\s@pex}{#1\s@pin}\edef\t@x{#2}\ifx\t@x\empty\relax \else 
  423.                       \s@pexpand #2!\fi}
  424.  
  425. % ========== A Do Loop Construction =========
  426. % \do <something> for <number of times>\od 
  427. % This is a specialization of the \loop in Plain.
  428.  
  429. \newcount\d@count 
  430. \gdef\do #1 for #2\od{\d@count=#2\loop #1 \ifnum\d@count>1\advance
  431.                             \d@count by -1\repeat}
  432.  
  433.  
  434. % ========= Graphics specials =======
  435. \xdef\o@form{}
  436. \gdef\penwidth #1 {\h@num{#1}{\d@umc}\edef\p@w{\the\d@umc}\ifp@down \g@save 
  437.                      \e@xtend{\o@form}{st \g@restore }
  438.                        \else \e@xtend{\o@form}{\p@w\b@ sl }\fi}
  439. \gdef\linecap #1 {\edef\s@lc{#1}\ifp@down \g@save 
  440.                      \e@xtend{\o@form}{st \g@restore }
  441.                        \else \e@xtend{\o@form}{\s@lc\b@ slc }\fi}
  442. \gdef\linejoin #1 {\edef\s@lj{#1}\ifp@down \g@save 
  443.                      \e@xtend{\o@form}{st \g@restore }
  444.                        \else \e@xtend{\o@form}{\s@lj\b@ slj }\fi}
  445. \gdef\lpatt p:#1 {\edef\v@p{#1 0}\ifp@down \g@save 
  446.                      \e@xtend{\o@form}{st \g@restore }
  447.                        \else \e@xtend{\o@form}{\v@p\b@ sd }\fi}
  448.  
  449.  
  450. % ==== parameters are in units of the nominal dimension \g@dim ======
  451.  
  452. \gdef\p@move #1#2#3{\i@h{#1}\i@v{#2}\e@xtend{\o@form}{\the\h@pos\b@ \the\v@pos\b@ #3 }}
  453.  
  454. \gdef\lvec h:#1 v:#2 {\p@move{#1}{#2}{lv}\p@downtrue} %draws a line 
  455.  
  456. \gdef\move h:#1 v:#2 {\p@move{#1}{#2}{mv}} %moves 
  457.  
  458.  
  459. % ======  a general  vector with dimensions in pixels ======
  460.  
  461. % ========= General pixel dim vector ==========
  462.  
  463. \gdef\lpix h:#1 v:#2 f:#3 {\e@xtend{\o@form}{ #1 #2 #3 }}
  464.  
  465.  
  466. %============== puts TeX text at this  position
  467. % These are pure TeX macros that use \h@pos and \v@pos for orientation
  468. % Text may be put horizontally (left/right) or vertically (down/up)
  469.  
  470. % ======== sp form of \h@pos and \v@pos respectively ========
  471. \newdimen\t@hpos
  472. \newdimen\t@vpos
  473. \gdef\s@ettpos{\d@umc=\h@pos
  474.                \genpixtopt{\t@hpos}{\d@umc}{\h@pix}{}{}\relax
  475.                \d@umc=\v@pos
  476.                \genpixtopt{\t@vpos}{\d@umc}{\v@pix}{}{}\relax}
  477.  
  478.  
  479.  
  480. % any one of nine reference point may be specified on the
  481. % TeX box. This is Vertical T,C,B and Horizontal L,C,R 
  482. % The actual box is 0 height and width. 
  483. \newbox\t@box 
  484. % #1 LCR default/error L #2 TCB default/error T #3 text -- in hbox
  485.  
  486. % Sets the box glues \lhglue \rhglue \tvglue \bvglue
  487. % #1 x/h ref, #2 v/y ref
  488. \gdef\textref h:#1 v:#2 {\ifx#1R\edef\lhglue{\hss}\edef\rhglue{}\else
  489.                              \ifx#1C\edef\lhglue{\hss}\edef\rhglue{\hss}\else
  490.                                \edef\lhglue{}\edef\rhglue{\hss}\fi\fi
  491.                           \ifx#2B\edef\tvglue{\vss}\edef\bvglue{}\else
  492.                              \ifx#2C\edef\tvglue{\vss}\edef\bvglue{\vss}\else
  493.                                \edef\tvglue{}\edef\bvglue{\vss}\fi\fi}
  494. \global\let\tboxref=\textref
  495.  
  496. \newcount\h@oldmaxpos \newcount\v@oldmaxpos
  497.  
  498.            %needed to save max pos when texgraph is inside an h/vtext
  499.  
  500. % ========== assumes driver location at initial \btg entry ========
  501.  
  502. % #1 text #2 - begin rotation form  #3 - end rotation form 
  503. \long\gdef\m@text#1#2#3{\g@raphout\h@oldmaxpos=\maxhpospix\relax 
  504.                         \v@oldmaxpos=\maxvpospix\relax 
  505.        \edef\h@oldgrsc{\h@grsc}\edef\v@oldgrsc{\v@grsc}\s@ettpos
  506.             \setbox\t@box=\vbox{\normalbaselines
  507.               \vskip\t@vpos\hbox{\hskip\t@hpos
  508.              \t@init{#2}\relax
  509.              \vbox to 0pt{\normalbaselines
  510.                           \tvglue\hbox to 0pt{\lhglue\hbox{#1}\rhglue
  511.                               }\bvglue}}}\relax
  512.           \dp\t@box=0pt\ht\t@box=0pt\wd\t@box=0pt 
  513.             \box\t@box
  514.              \t@fin{#3}
  515.             \global\maxhpospix=\h@oldmaxpos\relax 
  516.              \global\maxvpospix=\v@oldmaxpos\relax 
  517.             \xdef\h@grsc{\h@oldgrsc}\edef\v@grsc{\v@oldgrsc}}
  518.          % saves maxh(v)pospix on stack 
  519.  
  520.             
  521. % ========== PS text initializations and terminations ===========
  522. \gdef\t@init#1{\special{\p@sinline  td begin \h@vinit  gr gs 
  523.                          \t@rhv #1 \t@rneghv end }} 
  524.  
  525. \gdef\t@fin#1{\special{\p@sinline  td begin \h@vinit gr gs \m@vhv \t@rhv \p@hv end }}
  526.  
  527. % .... special test 
  528. %\gdef\t@init#1{}
  529. %\gdef\t@fin#1{}
  530. % ... end special test
  531.  
  532.  
  533.  
  534. \long\gdef\htext #1 {\m@text{#1}{}{}}
  535. \long\gdef\vtext #1 {\m@text{#1}{  90 \r@tdir rt }{}}
  536. \long\gdef\rtext d:#1 t:#2 {\m@text{#2}{ #1 \r@tdir rt }{}}
  537. \long\gdef\rstext d:#1 sc:#2 t:#3 {\m@text{#3}{ #1 \r@tdir rt #2 #2 sc }{}}
  538. \global\let\tbox=\htext
  539.  
  540. % ========= Various Restore forms ========
  541. \gdef\g@save{\edef\g@restore{\p@w\b@ sl \v@p\b@ sd \s@lc\b@ slc \s@lj\b@ slj
  542.                              np \the\h@pos\b@ \the\v@pos\b@ mv }}
  543. \gdef\s@save{\edef\s@restore{\p@w\b@ sl \v@p\b@ sd \s@lc\b@ slc \s@lj\b@ slj 
  544.                               np \the\h@pos\b@ \the\v@pos\b@ mv }}
  545.  
  546.  
  547.  
  548.  
  549. % ======== circle, arcs =========
  550. % The PS arc will connect the center of the arc to the circumference
  551. % if the newpath includes the move to this point. Thus we define a 
  552. % set of arc functions that include/exclude this feature. The default
  553. % does not include this form. 
  554.  
  555. \gdef\larc r:#1 sd:#2 ed:#3 {\h@num{#1}{\d@umc}\p@downtrue 
  556.              \e@xtend{\o@form}{ st np \the\h@pos\b@ \the\v@pos\b@ \the\d@umc\b@ #2 #3 arc
  557.                                 st np \the\h@pos\b@ \the\v@pos\b@ mv }}
  558.  
  559. \gdef\lcir r:#1 {\larc r:#1 sd:0 ed:360 }
  560.  
  561. % ------ this is a raw arc ... can be used in fills --------
  562.  
  563. \gdef\arcc r:#1 sd:#2 ed:#3 {\h@num{#1}{\d@umc}\p@downtrue 
  564.              \e@xtend{\o@form}{\the\h@pos\b@ \the\v@pos\b@ \the\d@umc\b@ #2 #3 arc }}
  565.  
  566. \gdef\arcn r:#1 sd:#2 ed:#3 {\h@num{#1}{\d@umc}\p@downtrue 
  567.              \e@xtend{\o@form}{\the\h@pos\b@ \the\v@pos\b@ 
  568.                        \the\d@umc\b@ #2 #3 arcn }}
  569.  
  570. % ======= fill command ==========
  571. % The fill command is essentially a polygonal fill ... not a point spreading
  572. % this means that it is possible to erase with white ... The form here
  573. % completes with a closepath applies the fill, starts a newpath and moves 
  574. % to the current point. Pattern is a grey level. 
  575. % 0 is black 1 is white 
  576.  
  577. \gdef\pfill p:#1 {\p@downtrue
  578.            \e@xtend{\o@form}{cp #1 sg fill np \the\h@pos\b@ \the\v@pos\b@ mv }}
  579.  
  580.  
  581. % this form both fills and strokes around the path 
  582. \gdef\lpfill p:#1 {\p@downtrue
  583.            \e@xtend{\o@form}{cp gs #1 sg fill gr st np \the\h@pos\b@ \the\v@pos\b@ mv }}
  584.  
  585. % ======== Postscript special forms ========
  586. % This allows "raw" postscript to be put in the graph. 
  587. \gdef\pst #1{\e@xtend{\o@form}{#1 }}
  588.  
  589. % These are some useful postscript compatible forms.
  590.  
  591. \gdef\closepath{\e@xtend{\o@form}{cp }}
  592. \gdef\newpath{\e@xtend{\o@form}{np }}
  593. \gdef\stroke{\e@xtend{\o@form}{st }}
  594.  
  595.  
  596.  
  597. % ========= including external files ==========
  598. % an external file is included at the present point on the graph area
  599. % moves are required to get there
  600. % The actual file is placed inside a \t@box and tex commands are used
  601. % to get to the place ... They probably can be nested 
  602. % #1 is the filename 
  603.  
  604. % The file is opened, if possible, to read its size. If this exists, it
  605. % is used to update the maximum h/v position. 
  606. % The BoundingBox is determined 
  607.  
  608.  
  609. \newread\q@file 
  610. % #1 is the file name
  611. \gnewif{\ifq@read}{\q@readtrue}{\q@readfalse}
  612. \gnewif{\ifq@file}{\q@filetrue}{\q@filefalse}
  613. \gnewif{\ifb@boxexists}{\b@boxexiststrue}{\b@boxexistsfalse}
  614. % #1 == %%BoundingBox, #2 llh #3 llv #4 urh #5 urv #6 rest of line  
  615.  
  616.  
  617. \gdef\uncat{\catcode`"=12}
  618.  
  619. {\catcode`\%=12 
  620. \gdef\l@shift{\ifx\l@lh\empty \xdef\l@lh{\l@lv}\xdef\l@lv{\u@rh}\xdef
  621.                                    \u@rh{\u@rv}\xdef\u@rv{\e@xt}\fi} 
  622. \gdef\B@Box{%%BoundingBox}
  623. \gdef\a@tend{(atend)}
  624. \gdef\a@tendtest{\l@shift\ifx\l@lh\a@tend\relax\else 
  625.            \global\b@boxexiststrue\q@readfalse\bmess{<< At End Test >>}\fi}
  626.         
  627. \long\gdef\q@inline #1:#2 #3 #4 #5 #6 #7//{\xdef
  628.                 \q@bbtest{#1}\xdef\l@lh{#2}\xdef
  629.           \l@lv{#3}\xdef\u@rh{#4}\xdef\u@rv{#5}\xdef
  630.                 \e@xt{#6}\ifx\q@bbtest\B@Box 
  631.              \a@tendtest\fi 
  632.              \ifeof\q@file \q@readfalse \fi}
  633.  
  634. \gdef\s@bbox{\b@boxexistsfalse
  635.              \message{<< \bbmess -- \f@ilename>>}\q@readtrue
  636.               \loop \relax \ifq@read\r@eadline\repeat}
  637.  
  638. \gdef\r@eadline{ {\uncat \global\read\q@file to\q@parms }
  639.   \expandafter\q@inline\q@parms {}:{\relax} {\relax} {\relax} {\relax}
  640. {\relax} \relax//\bmess{<<\q@parms>>}}
  641.  
  642. \gdef\g@etpsize #1{{\catcode`\%=12\openin\q@file = #1\relax
  643.                \edef\q@parms{}\global\q@filetrue\xdef\f@ilename{#1}
  644.                \ifeof\q@file \message{<<\noincfile: #1 >>}\relax
  645.                              \global\q@filefalse\else
  646.                    \s@bbox
  647.                   \closein\q@file\fi}}
  648.  
  649. } % end of % disable 
  650.  
  651. \newcount\h@px \newcount\v@px \newcount\h@mx \newcount\v@mx 
  652. \gdef\s@avemaxpos{\global\h@px=\maxhpospix\global\v@px=\maxvpospix
  653.                   \global\h@mx=\minhpospix\global\v@mx=\minvpospix}
  654. \gdef\r@estoremaxpos{\global\maxhpospix=\h@px\global\maxvpospix\v@px
  655.                   \global\minhpospix=\h@mx\global\minvpospix\v@mx}
  656.  
  657. \gdef\f@sc{\b@}
  658. \gdef\f@rt{\b@}
  659. \gdef\filerotate#1{\edef\f@rt{ XposR YposR tr   #1 \r@tdir rt XposR neg 
  660.                                YposR neg tr }}
  661.  
  662. \gdef\filescale #1{\edef\f@sc{#1 #1 sc \f@schv}}
  663. \gdef\p@fileinit{  td begin \h@vinit gr gs \f@rt \t@rhv \f@sc end  
  664.                    /texgraph save def  /showpage {} def }
  665. \xdef\p@filefin{ texgraph  restore }
  666. \global\let\mvec=\move
  667.  
  668.  
  669.  
  670. \gdef\includefile #1 {\incscfile f:{#1} sc:1 d:0 }
  671.  
  672. \gdef\incscfile f:#1 sc:#2 d:#3 {\g@etpsize{#1}\ifb@boxexists
  673.         \message{<<\incfile: #1 >>}\realadd{\u@rh}{-\l@lh}{\p@lh}
  674.                                    \realadd{\u@rv}{-\l@lv}{\p@lv}
  675.                                    \realmult{\p@lh}{.5}{\p@lhh}
  676.                                    \realmult{\p@lv}{.5}{\p@lvh}
  677.                             \beginsegment 
  678.                                \segmentscale #2 
  679.                                \global\let\g@dimo=\g@dim 
  680.                                 \graphdim  pt 
  681.                                  \mvec h:{\p@lh} v:{\p@lv}
  682.                                  \mvec h:{\p@lhh} v:{\p@lvh}
  683.                                  \m@text{}{ /XposR \Xpos\b@ def 
  684.                                             /YposR \Ypos\b@ def }{}  
  685.                             \endsegment
  686.                             \s@avemaxpos
  687.                             \beginsegment \segmentscale #2 
  688.                                   \mvec h:{-\l@lh} v:{\u@rv}
  689.                               \htext{\filescale{#2}\filerotate{#3}\relax
  690.                                 \special{\p@sinline\p@fileinit }
  691.                                 \special{\p@sfile  #1 }
  692.                                 \special{\p@sinline\p@filefin }}
  693.                             \endsegment
  694.                             \r@estoremaxpos 
  695.                             \global\let\g@dim=\g@dimo 
  696.                       \else\message{<<\badincfile: #1 >>}\fi  }
  697.  
  698. \gdef\incscmvfile f:#1 sc:#2 d:#3 h:#4 v:#5 {\g@etpsize{#1}\ifb@boxexists
  699.         \message{<<\incfile: #1 >>}\realadd{\u@rh}{-\l@lh}{\p@lh}
  700.                                    \realadd{\u@rv}{-\l@lv}{\p@lv}
  701.                                    \realmult{\p@lh}{.5}{\p@lhh}
  702.                                    \realmult{\p@lv}{.5}{\p@lvh}
  703.      \ifx#4L \edef\f@h{0}\else \ifx#4C \edef\f@h{1} \else \edef\f@h{2}\fi\fi 
  704.      \ifx#5T \edef\f@v{0}\else \ifx#5C \edef\f@v{1} \else\edef\f@v{2}\fi\fi
  705.                                    \realmult{\p@lhh}{\f@h}{\h@off}
  706.                                    \realmult{\p@lvh}{\f@v}{\v@off}
  707.                             \beginsegment 
  708.                                \segmentscale #2 
  709.                                \global\let\g@dimo=\g@dim 
  710.                                 \graphdim  pt 
  711.                                  \mvec h:{-\h@off} v:{-\v@off}
  712.                                \beginsegment
  713.                                  \mvec h:{\p@lh} v:{\p@lv}
  714.                                  \mvec h:{\p@lhh} v:{\p@lvh}
  715.                                  \m@text{}{ /XposR \Xpos\b@ def 
  716.                                             /YposR \Ypos\b@ def }{}
  717.                                \endsegment  
  718.                             \endsegment
  719.                             \s@avemaxpos
  720.                             \beginsegment \segmentscale #2 
  721.                                   \mvec h:{-\l@lh} v:{\u@rv}
  722.                              \beginsegment
  723.                               \mvec h:{-\h@off} v:{-\v@off}
  724.                               \htext{\filescale{#2}\filerotate{#3}\relax
  725.                                 \special{\p@sinline\p@fileinit }
  726.                                 \special{\p@sfile  #1 }
  727.                                 \special{\p@sinline\p@filefin }}
  728.                              \endsegment
  729.                             \endsegment
  730.                             \r@estoremaxpos 
  731.                             \global\let\g@dim=\g@dimo 
  732.                       \else\message{<<\badincfile: #1 >>}\fi  }
  733.  
  734.  
  735.  
  736. % ============ Design Grid ==============
  737. % This will lay down a grid at the present location. The grid nominally
  738. % at unit dimension intervals. The scale factor sc modifies this. The 
  739. % sc is local only to the grid 
  740.  
  741. \newcount\gcount 
  742. \gdef\grid nh:#1 nv:#2 sc:#3 {\gcount= #1 
  743.                               \beginsegment
  744.                               \relative
  745.                               \penwidth .005
  746.                               \graphscale #3 
  747.                               \beginsegment 
  748.                               \loop \lvec h:#2 v:0
  749.                                     \move h:-#2 v:1 
  750.                                     \ifnum \gcount > 1 
  751.                                       \advance\gcount by -1 \repeat
  752.                               \endsegment
  753.                               \gcount = #2
  754.                               \beginsegment 
  755.                               \loop \lvec h:0 v:#1 
  756.                                     \move h:1 v:-#1 
  757.                                     \ifnum \gcount > 1 
  758.                                       \advance\gcount by -1 \repeat
  759.                               \endsegment
  760.                               \endsegment}
  761. %========= end design grid ================
  762.  
  763.  
  764. % =========== Arrow Vectors ==============
  765. % There are three types of arrow heads, filled, open V and triangle
  766. % These are always placed on the end of a vector. 
  767.  
  768. % The basic design has the arrow head which is placed on the vector 
  769. % It theoretically can be placed on any curve where the angle is known or
  770. % computable. 
  771.  
  772.  
  773. \newcount\a@len
  774. \newcount\a@wid
  775.  
  776. % Parameter specification for arrowheads.
  777. % #1 -- length #2 -- width 
  778. % The dimensions are interpreted at current graphscale in force and
  779. % are local to the segment group.
  780. \gdef\arrowheadscale{\arrowheadsize l:.16 w:.04 }
  781. \gdef\arrowheadsize l:#1 w:#2 {\grdimtopix{#1}{\a@len}{\h@pix
  782.                                }\grdimtopix{#2}{\a@wid}{\h@pix
  783.                                 }}
  784. % postcript commands for inidividual arrow form 
  785. \gdef\arrowheadtype t:#1 {\ifx#1T\edef\a@com{cp gs 1 sg fill gr st }\else
  786.                           \ifx#1F\edef\a@com{cp 0 sg fill }\else
  787.                                  \edef\a@com{st }\fi\fi}
  788. \newcount\h@lp
  789. \newcount\v@lp 
  790.  
  791. % assumes that  the dh and dv is in \h@lp \v@lp and present location is tip
  792. % of arrowhead 
  793. \gdef\a@draw{st np \the\h@pos\b@ \the\v@pos\b@ mx 
  794.                    \the\v@lp\b@ neg \the\h@lp\b@  at  
  795.                     -\the\a@len\b@ \the\a@wid\b@ mv 0 0 lv 
  796.                     -\the\a@len\b@ -\the\a@wid\b@ lv 
  797.                      \a@com gr }
  798.                     
  799.                 
  800.  
  801. \gdef\avec h:#1 v:#2 {\h@lp=\h@pos\relax \v@lp=\v@pos\relax
  802.                       \lvec h:#1 v:#2 \advance\h@lp by -\h@pos\relax
  803.                                       \advance\v@lp by -\v@pos\relax
  804.                      \e@xtend{\o@form}{\a@draw}}
  805.  
  806.  
  807. % ============= End Arrow Vectors =============
  808.  
  809. % ========= Bezier Curve ==========
  810. % this is a cubic spline that is determined by four points. The initial 
  811. % point is assumed to be the current point. An arrow is easily added.
  812.  
  813.  
  814. \gdef\clvec h1:#1 v1:#2 h2:#3 v2:#4 h3:#5 v3:#6 {\i@h{#1}\d@uma=\h@pos
  815.             \i@v{#2}\d@umb=\v@pos\i@h{#3}\d@ume=\h@pos\i@v{#4}\d@umd=\v@pos
  816.             \i@h{#5}\i@v{#6}\e@xtend{\o@form}{\the\d@uma\b@ \the\d@umb\b@ 
  817.                   \the\d@ume\b@ \the\d@umd\b@ \the\h@pos\b@ \the\v@pos\b@ 
  818.                    cv }\p@downtrue}
  819. \gdef\clv (#1 #2) (#3 #4) (#5 #6){\clvec h1:#1 v1:#2 h2:#3 v2:#4 h3:#5 v3:#6 }
  820.  
  821. \gdef\cavec h1:#1 v1:#2 h2:#3 v2:#4 h3:#5 v3:#6 {\clvec h1:#1 v1:#2 h2:#3 v2:#4 h3:#5 v3:#6 
  822.                \h@lp=\d@ume \relax \v@lp=\d@umd \relax
  823.                \advance\h@lp by -\h@pos\relax
  824.                \advance\v@lp by -\v@pos\relax
  825.                 \e@xtend{\o@form}{\a@draw}}
  826. \gdef\cav (#1 #2) (#3 #4) (#5 #6){\cavec h1:#1 v1:#2 h2:#3 v2:#4 h3:#5 v3:#6 }
  827.  
  828.  
  829.  
  830.  
  831.  
  832. % ======= default values =========
  833. % These are reset each time \btg is called
  834. \gdef\t@exgraphdef{\setbox0=\hbox{}\graphdim in
  835. \hpix 300/in % INRS Default
  836. \vpix 300/in % INRS Default
  837. \printhv 1 1 % DVIPS 300 dpi
  838. \filehv 4.17 -4.17 % DVIPS 300/72
  839. \rtdir neg  % DVIPS
  840. \def\h@grsc{1}\def\v@grsc{1}%sets default hor/vert scales 
  841. \absoluteposition
  842. \relativescale
  843. \unitscale 1
  844. \penwidth .015
  845. \lpatt  p:{[]}
  846. \linecap 1
  847. \linejoin 1 
  848. \arrowheadsize l:.16 w:.04 
  849. \arrowheadtype t:T 
  850. \textref h:L v:T }
  851.  
  852. \xdef\s@egsc{1}% initial default 
  853.  
  854. \catcode`\@=12 
  855.  
  856.  
  857.  
  858.